#include "Hook_Scaleform.h"
#include "ScaleformFunctions.h"
#include "sfse_common/Log.h"
#include "my_classes/ScaleformGFxMovie.h"

using Scaleform::GFx::Value;

template <typename T>
void RegisterFunction(Value * dst, Scaleform::GFx::AS3::MovieRoot * movie, const char * name)
{
    Value fnValue;
    Scaleform::GFx::FunctionHandler	* fn = new T;
    movie->CreateFunction(&fnValue, fn);
    dst->SetMember(name, fnValue);
}

class Scaleform_GetSettings : public Scaleform::GFx::FunctionHandler
{
public:
    virtual void	Call(const Params* params) override
    {
        //_MESSAGE("%s", params->pArgs[0].GetString());
        auto mroot = params->pMovie->movieRoot;
        mroot->CreateObject(params->pRetVal);
        _MESSAGE("Scaleform_GetSettings called");
        Value _iX(iX), _iY(iY), _iFontSize(iFontSize), _sFont, _bShowSeconds(bShowSeconds) , _b12hFormat(b12hFormat);
        mroot->CreateObject(params->pRetVal);
        params->pRetVal->SetMember("iX", _iX);
        params->pRetVal->SetMember("iY", _iY);
        params->pRetVal->SetMember("iFontSize", _iFontSize);
        mroot->CreateString(&_sFont, sFont.c_str());
        params->pRetVal->SetMember("sFont", _sFont);
        params->pRetVal->SetMember("bShowSeconds", _bShowSeconds);
        params->pRetVal->SetMember("b12Format", _b12hFormat);
        
    }
};


bool MenuCallback(IMenu* menu)
{
    Value currentSWFPath("");
    std::string currentSWFPathString = "";
    auto mroot = menu->movie->movieRoot;
    if (!mroot) return false;
        if (mroot->GetVariable(&currentSWFPath, "root.loaderInfo.url"))
        {
            currentSWFPathString = currentSWFPath.GetString();
            for (auto f : menus)
            {
                if (currentSWFPathString.find(f.c_str()) != std::string::npos)
                {
                    _MESSAGE("menu from list hooking %s", f.c_str());

                    Value root;
                    if (currentSWFPathString.find("HUDMenu") != std::string::npos)
                        mroot->GetVariable(&root, "root1.TopCenterGroup_mc");
                    else mroot->GetVariable(&root, "root");
                    _MESSAGE("root set member helpers");
                    Value obj, _iX(iX), _iY(iY), _iFontSize(iFontSize), _sFont, _bShowSeconds(bShowSeconds) , _b12hFormat(b12hFormat);
                    mroot->CreateObject(&obj);
                    root.SetMember("helpers", obj);
                    obj.SetMember("iX", _iX);
                    obj.SetMember("iY", _iY);
                    obj.SetMember("iFontSize", _iFontSize);
                    mroot->CreateString(&_sFont, sFont.c_str());
                    obj.SetMember("sFont", _sFont);
                    obj.SetMember("bShowSeconds", _bShowSeconds);
                    obj.SetMember("b12hFormat", _b12hFormat);

                    //RegisterFunction<Scaleform_GetSettings>(&root, mroot, "GetSettings");
                    Value fnValue;
                    Scaleform::GFx::FunctionHandler	* fn = new Scaleform_GetSettings();
                    mroot->CreateFunction(&fnValue, fn);
                    obj.SetMember("GetSettings", fnValue);

                    _MESSAGE("root set member timer_loader");
                    Value loader, urlRequest;
                    Value timer("DEF_TOLS.swf");
                    mroot->CreateObject(&loader, "flash.display.Loader");
                    mroot->CreateObject(&urlRequest, "flash.net.URLRequest", &timer, 1);                    
                    root.SetMember("timer_loader", loader);

                    loader.Invoke("load", nullptr, &urlRequest, 1);
                    if (root.Invoke("addChild", nullptr, &loader, 1)) _MESSAGE("timer injectet");
                    //traceGFxValue(&root);
                }
            }
        }
    return true;
}


RelocAddr<uintptr_t> kHook_Scaleform_Log_Offset(0x407F828 + 0x08);

void Scaleform_LogMessageVarg(void* logger, u32 messageType, const char* fmt,
                              va_list args)
{
    std::string prefix = "[Scaleform] ";
    prefix += fmt;
    DebugLog::log(DebugLog::kLevel_Message, prefix.c_str(), args);
}

#include "sfse_common/SafeWrite.h"

void Hooks_Scaleform_Apply()
{
    safeWrite64(kHook_Scaleform_Log_Offset, (uintptr_t)Scaleform_LogMessageVarg);
}